package com.hjx.movie.core.system.controller.admin;

import com.hjx.movie.common.utils.Result;
import com.hjx.movie.common.utils.ResultType;
import com.hjx.movie.common.utils.exceptions.CustomException;
import com.hjx.movie.core.system.runner.SystemStaticData;
import com.hjx.movie.core.system.service.admin.IUserRoleService;
import com.hjx.movie.core.system.service.admin.IUserService;
import com.hjx.movie.core.system.service.commons.file.FileService;
import com.hjx.movie.core.system.vo.CheckedIdsVO;
import com.hjx.movie.core.system.vo.FileVo;
import com.hjx.movie.core.util.PasswordUtil;
import com.hjx.movie.persistence.system.groups.Update;
import com.hjx.movie.persistence.system.model.IvyMovie;
import com.hjx.movie.persistence.system.model.IvyUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.File;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.sql.SQLNonTransientException;
import java.util.Map;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/2 - 22:51
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    IUserService userService;
    @Resource
    IUserRoleService userRoleService;
    @Resource
    SystemStaticData staticData;

    @GetMapping("/info")
    public Result findUserInfo(@RequestParam(value="uid") String uid){
        return  Result.success(userService.getById(uid));
    }

    @RequestMapping("/findAll")
    @ResponseBody
    public Result findAll(){
        return Result.success(userService.list());
    }

    @PostMapping("/add")
    public Result addUserRandomPassword(@RequestBody @Valid IvyUser user){
        log.debug("接收到的入参:{}",user);
        String randomPassword = null;
        boolean flag = StringUtils.isNotBlank(user.getPassword());
        if (flag){
            if (user.getPassword().length()<6||user.getPassword().length()>20){
                return Result.error(ResultType.USER_INPUT_ERROR,"密码长度必须为6至20位");
            }
        }else {
            randomPassword = PasswordUtil.generateRandomPassword();
            log.debug("随机生成的密码为: {}",randomPassword);
            user.setPassword(randomPassword);
        }

        if (userService.insertUser(user)){
            StringBuilder text =  new StringBuilder("新增用户成功");
            if (!flag){
                text.append(",随机生成的密码为:").append(randomPassword);
            }
            return Result.success(text.toString());
        }
        return Result.error(ResultType.USER_INPUT_ERROR,"新增用户失败");
    }

    @GetMapping("/delete")
    public Result deleteUser(@RequestParam(value = "userId") Long userId){
        if (userService.deleteUser(userId)){
            return Result.success("删除成功");
        }
        return Result.error(ResultType.USER_INPUT_ERROR);
    }
    //使用了分组校验
    @PostMapping("/update")
    public Result updateUser(@RequestBody @Validated({Update.class}) IvyUser user){
        if (userService.updateUser(user)){
            return Result.success("修改成功");
        }
        return Result.error(ResultType.USER_INPUT_ERROR);
    }
    @PostMapping("/adminUpdatePassword")
    public Result adminUpdatePassword(@RequestBody Map<String,String> map){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String adminId = authentication.getName();
        String userId =map.get("userId");
        String adminPassword = map.get("adminPassword");
        String password = map.get("password");
        log.debug("接收到的入参为:adminId:{},adminPassword:{},userId:{},password:{}",adminId,adminPassword,userId,password);
        if (StringUtils.isNotBlank(adminId)&&StringUtils.isNotBlank(userId) &&StringUtils.isNotBlank(adminPassword) && StringUtils.isNotBlank(password)){
            if (userService.adminUpdatePassword(Long.valueOf(adminId),adminPassword,Long.valueOf(userId),password)) {
                return Result.success("管理员修改密码成功");
            }
        }
        return Result.error(ResultType.USER_INPUT_ERROR,"管理员修改密码失败");
    }
    @PostMapping("/userUpdatePassword")
    public Result userUpdatePassword(@RequestBody Map<String,String> map){
        String userId =map.get("userId");
        String oldPassword = map.get("oldPassword");
        String password = map.get("password");
        log.debug("接收到的入参为:{}",map.toString());
        if (StringUtils.isNotBlank(userId) &&StringUtils.isNotBlank(oldPassword) && StringUtils.isNotBlank(password)){
            // ^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$  ^(?![A-Za-z0-9]+$)(?![a-z0-9\W]+$)(?![A-Za-z\W]+$)(?![A-Z0-9\W]+$)[a-zA-Z0-9\W]{6,20}$
            if (password.matches("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$")){
                if (userService.userUpdatePassword(Long.valueOf(userId),oldPassword,password)) {
                    return Result.success("修改密码成功");
                }
            }else {
                // 密码不符合规范,密码必须是包含大写字母、小写字母、数字、特殊符号（不是字母，数字，下划线，汉字的字符）的6至20位的组合
                return Result.error(ResultType.USER_INPUT_ERROR,"密码不符合规范,密码必须是6至20位的数字和字母组成");
            }
        }
        return Result.error(ResultType.USER_INPUT_ERROR,"修改密码失败");
    }

    @GetMapping("/checkedRoles")
    public Result checkedRoles(@RequestParam("userId") Long userId){
        return Result.success(userRoleService.findCheckedAndRoleIds(userId));
    }

    @PostMapping("/addOrDeleteUserRole")
    public Result addOrDeleteUserRole(@RequestBody CheckedIdsVO checkedIdsVO){
        userRoleService.addOrDeleteUserRole(checkedIdsVO.getId(), checkedIdsVO.getCheckedIds());
        return Result.success("保存用户角色成功");
    }


    @RequestMapping("uploadUserPic")
    public Result fileUpload(MultipartFile file) {
        log.debug("{}",file);
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getName());
        log.debug("{}",userId);
        String realPath = userService.getUserHeadRealPath(userId);
        log.debug("realPath:{}",realPath);
        String name = FileService.fileUpload(file,realPath);
        // 头像路径存进数据库是以http格式存的
        String picPath = userId+"/"+name;
        userService.updateUser(IvyUser.builder().userId(userId).headPic(picPath).build());
        String url = staticData.getStaticValue("BASE_URL_USER_HEAD")+"/"+userId+"/"+name;
        FileVo fileVo = new FileVo(-1,name,"done",url,picPath);
        return Result.success(fileVo);
    }

    @GetMapping("queryUserLike")
    public Result queryUserLike(@RequestParam(value = "userLike") String str){
        if (StringUtils.isNotBlank(str)){
            return Result.success(userService.queryUserLike(str));
        }
        return Result.success(userService.list());
    }

    // 局部异常处理
    @ExceptionHandler(DuplicateKeyException.class)
    public Result errorHandler(){
        return Result.error(ResultType.USER_INPUT_ERROR,"用户名、邮箱或者电话号码已存在系统之中，请更换后再进行修改");
    }
}
